{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "#实现可迭代对象\n",
    "class MyRange:\n",
    "    def __init__(self, num):\n",
    "        self.i = 0\n",
    "        self.num = num\n",
    "\n",
    "    def __iter__(self):\n",
    "        return self\n",
    "\n",
    "    def __next__(self):\n",
    "        if self.i < self.num:\n",
    "            i = self.i\n",
    "            self.i += 1\n",
    "            return i\n",
    "        else:\n",
    "            raise StopIteration()\n",
    "\n",
    "for i in MyRange(6):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "0 ---> red\n",
      "1 ---> green\n",
      "2 ---> blue\n",
      "3 ---> yellow\n"
     ]
    }
   ],
   "source": [
    "for i in range(6):\n",
    "    print(i)\n",
    "\n",
    "colors = ['red','green','blue','yellow']\n",
    "for i, color in enumerate(colors):\n",
    "    print(i, '--->', color)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<zip object at 0x00000196126A3C00>\n",
      "[('raymond', 'red'), ('rachel', 'green'), ('matthew', 'blue')]\n",
      "raymond ---> red\n",
      "rachel ---> green\n",
      "matthew ---> blue\n"
     ]
    }
   ],
   "source": [
    "# 遍历两个集合\n",
    "names = ['raymond','rachel','matthew']\n",
    "colors = ['red','green','blue','yellow']\n",
    "print(zip(names, colors)) #返回是一个对象\n",
    "print(list(zip(names, colors))) #list转换为列表\n",
    "for name, color in zip(names, colors):\n",
    "    print(name, '--->', color)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-1\n"
     ]
    }
   ],
   "source": [
    "# 循环内需要识别多个退出点，推荐使用for-else\n",
    "def  find(seq, target):\n",
    "    for i,value in enumerate(seq):\n",
    "        if value == target:\n",
    "            break\n",
    "    else:\n",
    "        return -1\n",
    "    return i\n",
    "print(find(range(10,20), 30))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mattew\n",
      "rachel\n",
      "raymond\n",
      "blue\n",
      "green\n",
      "red\n",
      "('mattew', 'blue')\n",
      "('rachel', 'green')\n",
      "('raymond', 'red')\n",
      "mattew ---> blue\n",
      "rachel ---> green\n",
      "raymond ---> red\n",
      "dict_keys(['mattew', 'rachel', 'raymond'])\n",
      "['mattew', 'rachel', 'raymond']\n",
      "dict_keys(['mattew'])\n"
     ]
    }
   ],
   "source": [
    "d = {'mattew':'blue', 'rachel':'green', 'raymond': 'red'}\n",
    "for k in d.keys():\n",
    "    print(k)\n",
    "\n",
    "for k in d.values():\n",
    "    print(k)\n",
    "\n",
    "for k in d.items():\n",
    "    print(k)\n",
    "\n",
    "for k, v in d.items():\n",
    "    print(k, '--->', v)\n",
    "\n",
    "print(d.keys())\n",
    "print(list(d.keys()))\n",
    "\n",
    "for k in list(d.keys()):\n",
    "    if k.startswith('r'):\n",
    "        del d[k]\n",
    "\n",
    "print(d.keys())\n",
    " \n",
    "for k in d.keys():\n",
    "    if k.startswith('r'):\n",
    "        del d[k]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "<generator object gensquares at 0x000001961273E4D0>\n",
      "0\n",
      "1\n",
      "4\n",
      "9\n",
      "16\n",
      "<generator object <genexpr> at 0x000001961273E4D0>\n",
      "0\n",
      "1\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "#生成器\n",
    "a = [x for x in range(10)]\n",
    "print(a)\n",
    "\n",
    "#函数方式实现生成器\n",
    "def gensquares(N):\n",
    "    for i in range(N):\n",
    "        yield i**2\n",
    "\n",
    "print(gensquares(5))\n",
    "for i in gensquares(5):\n",
    "    print(i)\n",
    "\n",
    "a = ((x**2) for x in range(5))\n",
    "print(a)\n",
    "print(next(a))\n",
    "print(next(a))\n",
    "print(next(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time used1: 0.04883020000124816\n",
      "Time used1: 0.04921839998860378\n",
      "Time used2: 0.060533800002303906\n",
      "Time used1: 0.05486629999359138\n",
      "Time used1: 0.05290539999259636\n",
      "Time used1: 0.05017570000200067\n",
      "Time used1: 0.04683379999187309\n",
      "Time used1: 0.046539500006474555\n",
      "Time used3: [0.06874620000598952, 0.06487300001026597, 0.06033440001192503, 0.05836889999045525, 0.055414999995264225]\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "#创建一个元素为递增的整数列表\n",
    "def for_generate_list(size = 1000000):\n",
    "    start = time.perf_counter()\n",
    "    my_list = []\n",
    "    for num in range(size):\n",
    "        my_list.append(num)\n",
    "    elapsed = (time.perf_counter() - start)\n",
    "    print('Time used1: {}'.format(elapsed))\n",
    "\n",
    "for_generate_list()\n",
    "from timeit import timeit\n",
    "elapsed=timeit(stmt='for_generate_list()',setup='from __main__ import for_generate_list',number=1)\n",
    "print(\"Time used2:\", elapsed)\n",
    "\n",
    "from timeit import repeat\n",
    "t_elapsed = repeat(stmt='for_generate_list()', setup='from __main__ import for_generate_list', number=1, repeat=5)\n",
    "print(\"Time used3:\",t_elapsed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "list size is: 1000000 \n",
      "Time used: 0.05799200000183191 \n"
     ]
    }
   ],
   "source": [
    "#定义测试代码执行时间的装饰器\n",
    "def timeit_test(func):\n",
    "    def wrapper(*args, **kwargs):\n",
    "        start = time.perf_counter()\n",
    "        func(*args, **kwargs)\n",
    "        elapsed = (time.perf_counter() - start)\n",
    "        print('Time used: {} '.format(elapsed))\n",
    "    return wrapper\n",
    "\n",
    "@timeit_test\n",
    "def for_generate_list(size = 1000000):\n",
    "    print('list size is: {} '.format(size))\n",
    "    my_list = []\n",
    "    for num in range(size):\n",
    "        my_list.append(num)\n",
    "    \n",
    "for_generate_list(1000000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "list size is: 900000 \n",
      "list size is: 900000 \n",
      "Time of 0 used: 0.10740389999409672 \n",
      "list size is: 900000 \n",
      "list size is: 900000 \n",
      "Time of 1 used: 0.09688660000392701 \n"
     ]
    }
   ],
   "source": [
    "#定义测试代码执行时间的装饰器--三阶\n",
    "def timeit_test(number=3, repeat=3):\n",
    "    def decorator(func):\n",
    "        def wrapper(*args, **kwargs):\n",
    "            for i in range(repeat):\n",
    "                start = time.perf_counter()\n",
    "                for _ in range(number):\n",
    "                    func(*args, **kwargs)\n",
    "                elapsed = (time.perf_counter() - start)\n",
    "                print('Time of {} used: {} '.format(i, elapsed))\n",
    "        return wrapper\n",
    "    return decorator\n",
    "\n",
    "@timeit_test(number = 2, repeat = 2)\n",
    "def for_generate_list(size = 1000000):\n",
    "    print('list size is: {} '.format(size))\n",
    "    my_list = []\n",
    "    for num in range(size):\n",
    "        my_list.append(num)\n",
    "\n",
    "for_generate_list(900000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_normal 1.9569819000025745\n",
      "test_Process 2.556847200001357\n",
      "test_Thread 1.9779011000064202\n"
     ]
    }
   ],
   "source": [
    "from timeit import timeit\n",
    "#CPU密集型任务\n",
    "def count(n):\n",
    "    while n > 0:\n",
    "        n -= 1\n",
    "\n",
    "from threading import Thread\n",
    "from multiprocessing import Process\n",
    "from timeit import timeit\n",
    "\n",
    "# 单线程方式\n",
    "def test_normal():\n",
    "    count(1000000)\n",
    "    count(1000000)\n",
    "\n",
    "#多线程方式\n",
    "def test_Thread():\n",
    "    t1 = Thread(target=count, args=(1000000,))\n",
    "    t2 = Thread(target=count, args=(1000000,))\n",
    "    t1.start()\n",
    "    t2.start()\n",
    "    t1.join()\n",
    "    t2.join()\n",
    "\n",
    "#多进程方式\n",
    "def test_Process():\n",
    "    t1 = Process(target=count, args=(1000000,))\n",
    "    t2 = Process(target=count, args=(1000000,))\n",
    "    t1.start()\n",
    "    t2.start()\n",
    "    t1.join()\n",
    "    t2.join()\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    print(\"test_normal\", timeit('test_normal()','from __main__ import test_normal', number = 30))\n",
    "    print('test_Process', timeit('test_Process()', 'from __main__ import test_Process', number = 30))\n",
    "    print(\"test_Thread\",timeit('test_Thread()','from __main__ import test_Thread', number = 30))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_normal 0.6225971999956528\n",
      "test_Process 2.915208200007328\n",
      "test_Thread 0.34399179999309126\n"
     ]
    }
   ],
   "source": [
    "from timeit import timeit\n",
    "#IO密集型任务\n",
    "def count(n):\n",
    "   time.sleep(0.01)\n",
    "\n",
    "from threading import Thread\n",
    "from multiprocessing import Process\n",
    "from timeit import timeit\n",
    "\n",
    "# 单线程方式\n",
    "def test_normal():\n",
    "    count(1000000)\n",
    "    count(1000000)\n",
    "\n",
    "#多线程方式\n",
    "def test_Thread():\n",
    "    t1 = Thread(target=count, args=(1000000,))\n",
    "    t2 = Thread(target=count, args=(1000000,))\n",
    "    t1.start()\n",
    "    t2.start()\n",
    "    t1.join()\n",
    "    t2.join()\n",
    "\n",
    "#多进程方式\n",
    "def test_Process():\n",
    "    t1 = Process(target=count, args=(1000000,))\n",
    "    t2 = Process(target=count, args=(1000000,))\n",
    "    t1.start()\n",
    "    t2.start()\n",
    "    t1.join()\n",
    "    t2.join()\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    print(\"test_normal\", timeit('test_normal()','from __main__ import test_normal', number = 30))\n",
    "    print('test_Process', timeit('test_Process()', 'from __main__ import test_Process', number = 30))\n",
    "    print(\"test_Thread\",timeit('test_Thread()','from __main__ import test_Thread', number = 30))\n",
    "\n",
    "#全局解释器锁（global interpreter lock）管理线程的执行，必须先竞争到GIL权限才能执行。\n",
    "#CPU密集型线程时，解释器会每隔一定周期进行检查，在检查中会释放当前线程的GIL权限，并根据线程优先级将GIL权限重新分配给其他线程\n",
    "#IO密集型线程时，会在I/O阻塞时释放GIL\n",
    "#多线程无法利用多核参与计算，但多线程之间周期切换的开销时间依然存在，因此多线程比单一线程执行需要更多的时间，而多进程中有各自独立的GIL锁互不影响\n",
    "#多线程在挂起I/O任务时会释放GIL，允许其它并发线程执行，提升了运行程序的效率。而多进程创建和销毁的开销比多线程大，降低了多进程执行的效率。\n",
    "#多线程适合I/O密集型应用，多进程适合CPU密集型"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
